package com.xbongbong.paas.toolbox.util;

import com.xbongbong.paas.constant.PaasConstant;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * 为外链深层一个token处理与校验
 *
 * @author chenshan
 * @version v1.0
 * @since 2020/8/10 7:04 下午
 */
public class OuterTokenUtil {
    private static List<String> random = Arrays.asList("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "b", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z");
    
    
    public static void main(String[] args) throws Exception {
//    token生成规则 MD5的值，数字相加,字母不区分大小写统一取值后相乘，最后在相加，取莫作为最后一位校验位
        String tokenStr = getEncryptToken(1L, "1", 201, 1,"");
        System.out.println(tokenStr);
        tokenStr = "8ec1cb0156f574d0e3a2069b82038d290";
        System.out.println(getDecryptToken(tokenStr));
    }
    
    //字母转数字  A-Z ：1-26
    public static long letterToNumber(String letter) {
        int length = letter.length();
        int num = 0;
        int number = 0;
        for ( int i = 0; i < length; i++ ) {
            char ch = letter.charAt(length - i - 1);
            num = (int) (ch - 'A' + 1);
            num *= Math.pow(26, i);
            number += num;
        }
        return number;
    }
    
    public static int getNumberText(String str, List<String> letterList) {
        if ( StringUtil.isEmpty(str) ) {
            throw new RuntimeException("参数str不能为空");
        }
        Integer count = 0;
        String[] strArray = str.split("");
        for ( String s : strArray ) {
            if ( StringUtil.isNotEmpty(s) && RegexUtil.isNumber(s) ) {
                count += Integer.valueOf(s);
            } else if ( StringUtil.isNotEmpty(s) && !RegexUtil.isNumber(s) ) {
                letterList.add(s);
            }
        }
        return count;
    }
    
    public static String getEncryptToken(Long formId, String corpid, Integer businessType, Integer type,String extension) {
        String str = corpid + formId + businessType + type + extension;
        String tokenStr = DigestUtil.Encrypt(str, "MD5");
        String token = getEncryptToken(tokenStr);
        return token;
    }

    public static String getEncryptToken(Long formId, String corpid, Integer businessType, Integer type, Long dataId, String createrId) {
        String str = corpid + formId + businessType + type + dataId + createrId;
        String tokenStr = DigestUtil.Encrypt(str, "MD5");
        String token = getEncryptToken(tokenStr);
        return token;
    }
    
    public static String getEncryptToken(String tokenStr) {
        List<String> letterList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        long number = getNumberText(tokenStr, letterList);
        long count = 1;
        for ( String s : letterList ) {
            long number1 = letterToNumber(s.toUpperCase());
            count = count + number1;
        }
        int num = (int) ((number + count) % 36);
        tokenStr = tokenStr + random.get(num);
        return tokenStr;
    }
    
    public static Boolean getDecryptToken(String token) {
        Boolean isExist = false;
        String tokenStr = token.substring(0, token.length() - 1);
        String calculateToken = getEncryptToken(tokenStr);
        if ( Objects.equals(calculateToken, token) ) {
            isExist = true;
        }
        return isExist;
    }
    
}
